package ui.popup 
{	
	import com.GCItem;
	import com.GCInventory;
	import com.GCShip;
	import data.GCItemData;
	import data.GCShipData;
	import events.GCEvent;
	import events.GCUpgradeEvent;
	import ui.GCUpgradeSprite;
	import ui.button.GCButton;
	import ui.list.GCItemScrollList;
		
	import flash.display.Sprite;	
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.utils.Dictionary;
	
	/**
	 * A popup that allows a player to select whether they want to
	 * discard an upgrade or add a new one to their ship.
	 */
	public class GCUpgradePopup extends Sprite 
	{
		// The scroll list for all upgrades in player inventory
		private var _upgradeScrollList:GCItemScrollList;
		
		// Description
		private var _upgradeDescriptionArea:Sprite;			// Overall Area for description
		private var _descriptionText:TextField;				// General item description displayed here
		private var _abilityText:TextField;					// Describes the stat effects of the upgrade
		
		// Current upgrade
		//private var _currentUpgradeDisplay:Sprite;			// Displays slot for the current equip
		public var _slotOnFocus:GCUpgradeSprite;			// Which upgrade slot which was clicked on to bring the player here
		private var _upgradeIdOnFocus:uint;					// The item id of the upgrade that the player selected from the list
		private var _selectedUpgradeItem:GCItem;			// The actual item object selected by the player
		
		// Buttons
		private var _addUpgradeButton:GCButton;
		private var _discardUpgradeButton:GCButton;
		private var _upgradeInfoCloseButton:GCButton;
		
		// Background
		private var _backgroundImage:Sprite;
		
		/**
		 * Constructor
		 */
		public function GCUpgradePopup()
		{			
			_upgradeScrollList = new GCItemScrollList(200, 300);

			_upgradeDescriptionArea = new Sprite();
			_descriptionText = new TextField();
			_abilityText = new TextField();
			
			_slotOnFocus = null;
			_upgradeIdOnFocus = 0;
			_selectedUpgradeItem = null;
			
			_addUpgradeButton = new GCButton(onAddUpgrade);
			_discardUpgradeButton = new GCButton(onDiscardUpgrade);
			_upgradeInfoCloseButton = new GCButton(onCloseInfoArea);
			
			init();
		}
		
		private function init():void
		{
			// Upgrade Scroll List Area
			_upgradeScrollList.addEventListener(GCEvent.LIST_ITEM_SELECTED_EVENT, onItemSelected);
			_upgradeScrollList.setFilter(GCItemData.ITEM_TYPE_UPGRADE);
			_upgradeScrollList.x = 10;
			_upgradeScrollList.y = 10;			
			
			
			// Description Area
			_upgradeDescriptionArea.graphics.beginFill(GCConstants.COLOR_BLACK, .7);
			_upgradeDescriptionArea.graphics.drawRoundRect(0, 0, 200, 300, 20);
			_upgradeDescriptionArea.x = _upgradeScrollList.x + _upgradeScrollList.width + 50;
			_upgradeDescriptionArea.y = _upgradeScrollList.y;
			
			_descriptionText.text = "";
			_descriptionText.autoSize = TextFieldAutoSize.LEFT;
			_descriptionText.textColor = GCConstants.COLOR_WHITE;
			_descriptionText.wordWrap = true;
			_descriptionText.x = 10;
			_descriptionText.y = 10;			
			_upgradeDescriptionArea.addChild(_descriptionText);
			
			_abilityText.text = "";
			_abilityText.autoSize = TextFieldAutoSize.LEFT;
			_abilityText.x = _descriptionText.x;
			_abilityText.y = _descriptionText.y + _descriptionText.height;
			_upgradeDescriptionArea.addChild(_abilityText);

			// Buttons
			_addUpgradeButton.loadGraphic(GCResources.plate, 100, 30);
			_addUpgradeButton.loadText("Add Selected Upgrade");
			_addUpgradeButton.x = _upgradeScrollList.x;
			_addUpgradeButton.y = _upgradeScrollList.y + _upgradeScrollList.height + 20;
			//_addUpgradeButton.x = _upgradeDescriptionArea.x;
			//_addUpgradeButton.y = _upgradeDescriptionArea.y + _upgradeDescriptionArea.height + 20;;
			
			_discardUpgradeButton.loadGraphic(GCResources.plate, 100, 30);
			_discardUpgradeButton.loadText("Discard Upgrade");
			_discardUpgradeButton.x = _addUpgradeButton.x + _addUpgradeButton.width;
			_discardUpgradeButton.y = _addUpgradeButton.y;
			
			_upgradeInfoCloseButton.loadGraphic(GCResources.plate, 100, 30);
			_upgradeInfoCloseButton.loadText("Close");
			_upgradeInfoCloseButton.x = _discardUpgradeButton.x + _discardUpgradeButton.width;
			_upgradeInfoCloseButton.y = _discardUpgradeButton.y;			
			
			// Add all of the UI Elements
			//this.addChild(_slotOnFocus);
			this.addChild(_upgradeDescriptionArea);
			this.addChild(_upgradeScrollList);
			this.addChild(_addUpgradeButton);
			this.addChild(_discardUpgradeButton);
			this.addChild(_upgradeInfoCloseButton);
			
			//Popup background
			_backgroundImage = GCResources.getMaskedCanvasBackground(this.width + 20, this.height + 20);
			this.addChildAt(_backgroundImage, 0);
		}
		
		
		//----------------------------------------------------------------------
		//	PUBLIC FUNCTIONS
		//----------------------------------------------------------------------	
		
		public function openPopup(slot:GCUpgradeSprite):void
		{
			_slotOnFocus = slot;
			
			//_slotOnFocus.x = _upgradeScrollList.x;
			//_slotOnFocus.y = _upgradeScrollList.y + _upgradeScrollList.height + 10;
			//this.addChild(_slotOnFocus);
			
			if (_slotOnFocus.isEmpty)
			{
				_addUpgradeButton.enable();
				_discardUpgradeButton.disable();
				
				// If the slot is empty we do not give the ability to discard an item
				getAvailableUpgrades();
			}
			else
			{
				_addUpgradeButton.disable();
				_discardUpgradeButton.enable();
				
				// If clicked on a pre-exisiting upgrade, then we allow them to only 
				// dicard an upgrade
				var upgradeId:uint = _slotOnFocus.upgradeItemId;
				fillUpgradeDescription(upgradeId);
			}			
		}
		
		//----------------------------------------------------------------------
		//	PRIVATE FUNCTIONS
		//----------------------------------------------------------------------
		
		/**
		 * Get all items in the ship inventory that are of type upgrade.
		 */
		private function getAvailableUpgrades():void
		{
			var shipInv:GCInventory = GCPlayState.getPlayerInventory();
			_upgradeScrollList.setFilter(GCItemData.ITEM_TYPE_UPGRADE);
			_upgradeScrollList.loadInventory(shipInv);
		}
		
		/**
		 * Given the id of an upgrade, fill in the description of that upgrade.
		 * 
		 * @param	upgradeId
		 */		
		private function fillUpgradeDescription(upgradeId:uint):void
		{
			// Fill in the name and description of this upgrade
			_descriptionText.text = GCItemData.getNameFromId(upgradeId) + 
									"\n\nDescription:\n\n" + GCItemData.getItemDescriptionFromId(upgradeId);
			
			// Fill in the abilities
			var abilities:Dictionary = GCItemData.getUpgradeEnhancementsFromId(upgradeId);
			var xPos:int = _descriptionText.x;
			var yPos:int = _descriptionText.y + _descriptionText.height;
			
			var abilityDesc:String = "Stats:\n";
			for (var obj:Object in abilities)
			{
				var type:uint = obj as uint;
				var enhancementChange:int = abilities[type];
				switch(type)
				{
					case GCShipData.STAT_HULL:
						abilityDesc += "Increases your ship's capacity by ";
						break;
					case GCShipData.STAT_SLOTS:
						abilityDesc += "Increases the number of upgrade slots on your ship by ";
						break;
					case GCShipData.STAT_SPEED:
						abilityDesc += "Increases ship speed by ";
						break;
					case GCShipData.STAT_DEFENSE:
						abilityDesc += "Increases ship defense by ";
						break;
					case GCShipData.STAT_NAVIGATION:
						abilityDesc += "Increases navigation ability by ";
						break;
					case GCShipData.STAT_MAINTENANCE:
						abilityDesc += "Upgrades maintenance by ";
						break;
					case GCShipData.STAT_FUEL_EFFICIENCY:
						abilityDesc += "Upgrades fuel efficiency by ";
						break;
					default:
						break;
				}
				abilityDesc += String(enhancementChange);
				abilityDesc += "\n"
			}
			
			_descriptionText.appendText("\n\n" + abilityDesc);			
		}

		private function performUpgradeAdd():void
		{
			var addEvent:GCUpgradeEvent = new GCUpgradeEvent(GCEvent.POPUP_CLOSED_EVENT, true);
			addEvent._upgradeComponent = _slotOnFocus;
			addEvent.upgradeItemId = _upgradeIdOnFocus;
			addEvent.upgradeSlotId = _slotOnFocus.upgradeSlotId;
			addEvent.upgradeAction = GCUpgradeEvent.ADD_UPGRADE_EVENT;
			dispatchEvent(addEvent);
			
			_upgradeScrollList.clearSelecton();
			
			onCloseInfoArea(null);
		}
		
		/**
		 * 
		 */
		private function performUpgradeDiscard():void
		{
			var discardEvent:GCUpgradeEvent = new GCUpgradeEvent(GCEvent.POPUP_CLOSED_EVENT, true);
			discardEvent._upgradeComponent = _slotOnFocus;
			discardEvent.upgradeSlotId = _slotOnFocus.upgradeSlotId;
			discardEvent.upgradeAction = GCUpgradeEvent.DISCARD_UPGRADE_EVENT;
			dispatchEvent(discardEvent);
			onCloseInfoArea(null);
		}
		
		private function onExitCleanup():void
		{
			// Disable the buttons
			_addUpgradeButton.disable();
			_discardUpgradeButton.disable();
			
			// Clear out the text
			_abilityText.text = "";
			_descriptionText.text = "";
		}		
		
		
		
		//----------------------------------------------------------------------
		//	EVENT HANDLERS
		//----------------------------------------------------------------------
		
		/**
		 * Triggered when the user wants to add an upgrade to a previously
		 * empty slot.
		 * 
		 * @param	event
		 */
		private function onAddUpgrade(event:MouseEvent):void
		{
			if (_upgradeScrollList.selected == null)
				return;
				
			_selectedUpgradeItem =  _upgradeScrollList.selected.reference;
			_upgradeIdOnFocus = _selectedUpgradeItem.itemId;
			var currentShip:GCShip = GCPlayState.getCurrentShip();
			
			if (GCConstants.DEBUG_MODE)
			{
				performUpgradeAdd();
			}
			else
			{
				var itemIdToDB:uint = _upgradeIdOnFocus
				
				// Permanent upgrades must be handled slightly different
				if (GCItemData.isUpgradePermanentFromId(_upgradeIdOnFocus))
				{
					var enhancements:Dictionary = GCItemData.getUpgradeEnhancementsFromId(_upgradeIdOnFocus);
					
					for (var obj:Object in enhancements)
					{
						var enhanceType:uint = obj as uint;
						var enhanceAmount:uint = enhancements[enhanceType];
						
						currentShip.boosts[enhanceType] += enhanceAmount;
					}
					
					itemIdToDB = GCItemData.ITEM_NULL;
				}
				
				//DATABASE CALL- Add an upgrade to the ship (possibly boosts were changed above)
				GCUtil.equipItemToShip(currentShip.shipId, _slotOnFocus.upgradeSlotId, itemIdToDB, currentShip.boosts[GCShipData.STAT_HULL], 
					currentShip.boosts[GCShipData.STAT_DEFENSE], currentShip.boosts[GCShipData.STAT_SPEED], currentShip.boosts[GCShipData.STAT_NAVIGATION],
					currentShip.boosts[GCShipData.STAT_SLOTS], 0, function(code:uint, data:Object):void
				{
					var numUpgrades:uint = GCPlayState.getPlayerInventory().getItemFromId(_upgradeIdOnFocus).quantity;
					// Nested DB call, must now remove the item from the player's inventory
					GCUtil.updateItemQuantity(_selectedUpgradeItem.invItemId, numUpgrades - 1, function(code:uint, data:Object):void
					{
						trace("DATABASE-- removed upgrade from inventory");
					});
					
					performUpgradeAdd();
				});
			}
		}		
		
		/**
		 * Triggered when the user wants to discard a previously
		 * equipped upgrade on his ship.
		 * 
		 * @param	event
		 */
		private function onDiscardUpgrade(event:MouseEvent):void
		{
			var currentShip:GCShip = GCPlayState.getCurrentShip();
			
			if (GCConstants.DEBUG_MODE)
			{
				performUpgradeDiscard();
			}
			else
			{
				//DATABASE CALL- Remove an upgrade from a ship
				GCUtil.equipItemToShip(currentShip.shipId, _slotOnFocus.upgradeSlotId, GCItemData.ITEM_NULL, currentShip.boosts[GCShipData.STAT_HULL], 
					currentShip.boosts[GCShipData.STAT_DEFENSE], currentShip.boosts[GCShipData.STAT_SPEED], currentShip.boosts[GCShipData.STAT_NAVIGATION],
					currentShip.boosts[GCShipData.STAT_SLOTS], 0, function(code:uint, data:Object):void
				{
					trace("DATABASE- Discarding a previously equiped upgrade.");
					performUpgradeDiscard();
				});
			}
			
			function performUpgradeDiscard():void
			{
				var discardEvent:GCUpgradeEvent = new GCUpgradeEvent(GCEvent.POPUP_CLOSED_EVENT, true);
				discardEvent._upgradeComponent = _slotOnFocus;
				discardEvent.upgradeSlotId = _slotOnFocus.upgradeSlotId;
				discardEvent.upgradeItemId = _slotOnFocus.upgradeItemId;
				discardEvent.upgradeAction = GCUpgradeEvent.DISCARD_UPGRADE_EVENT;
				dispatchEvent(discardEvent);
				onCloseInfoArea(null);
			}
		}
		
		/**
		 * Triggered when the user wants to close the upgrade description
		 * area.
		 * 
		 * @param	event
		 */
		private function onCloseInfoArea(event:MouseEvent):void
		{
			// Dispatch event only if we got here by the user clicking the cancel button.
			if (event != null)
			{
				var cancel:GCUpgradeEvent = new GCUpgradeEvent(GCEvent.POPUP_CLOSED_EVENT);
				cancel.upgradeAction = GCUpgradeEvent.NO_UPGRADE_EVENT;
				dispatchEvent(cancel);
			}
			onExitCleanup();
		}
		
		private function onItemSelected(event:Event):void
		{
			_selectedUpgradeItem = _upgradeScrollList.selected.reference;
			this.fillUpgradeDescription(_selectedUpgradeItem.itemId);
		}		
		
	}	
}



		
		



